package com.base.loadbalancer;

import com.base.core.lang.StringUtils;

import java.util.List;

/**
 * 负载均衡工厂
 * 使用说明:
 * 工厂模式
 * ILoadBalancer<String, Object> loadBalancer = LoadBalancerFactory.build("Hash");
 * loadBalancer.addTargets(Arrays.asList("t1", "t2", "t3"), true);
 * loadBalancer.choose();
 * // loadBalancer.choose(new Object());
 * 构造器方法
 * ILoadBalancer<String, Object> loadBalancer = new HashLoadBalancer<>();
 * loadBalancer.addTargets(Arrays.asList("t1", "t2", "t3"), true);
 * loadBalancer.choose();
 * // loadBalancer.choose(new Object());
 * 设置对象权重
 * loadBalancer.setWeight(target, 1);
 *
 */
public class LoadBalancerFactory {

    /**
     * 按照约定规则创建
     *
     * @param rule
     *         加载器规则
     * @param <T>
     *         目标对象类
     * @param <C>
     *         选择引用对象
     * @return load balancer instance
     */
    public static <T, C> LoadBalancer<T, C> build(String rule) {
        return build(rule, null);
    }

    /**
     * build load balancer instance by appoint rule
     *
     * @param rule
     *         load balance rule
     * @param targetList
     *         target object list
     * @param <T>
     *         target object class
     * @param <C>
     *         选择引用对象
     * @return load balancer instance
     */
    public static <T, C> LoadBalancer<T, C> build(String rule, List<TargetWrapper<T>> targetList) {

        rule = StringUtils.capCamelCase(rule, "-".charAt(0));
        String instanceClassName = "com.base.loadbalancer.support." + rule + "LoadBalancer";

        try {
            Class<?> clazz = LoadBalancerFactory.class.getClassLoader().loadClass(instanceClassName);

            if (targetList == null) {
                return (LoadBalancer<T, C>) clazz.getConstructor().newInstance();
            } else {
                return (LoadBalancer<T, C>) clazz.getConstructor(List.class).newInstance(targetList);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getLocalizedMessage(), e);
        }
    }
}
